package com.tools.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;

public class NumberUtils
{

	static final String FMT_INT_PART = "################################0";
	static final String FMT_INT_PART_SOUTHAND = "###,###,###,###,###,###,###,###,###,##0";
	static final String FMT_DECIMAL_PART_NOZERO = "##########";
	static final String FMT_DECIMAL_PART_ZERO = "0000000000";

	private NumberUtils()
	{
	}

	private static double round(double d, int scale, int roundModle)
	{
		if (scale < 0)
			scale = 0;
		BigDecimal b = new BigDecimal(Double.toString(d));
		return b.divide(new BigDecimal("1"), scale, roundModle).doubleValue();
	}

	private static String formatDouble(double d, String fmtStr)
	{
		DecimalFormat df = new DecimalFormat(fmtStr);
		return df.format(d);
	}

	private static String formatDouble(double d, int scale, int roundModle, boolean thousandSplit, boolean decMust)
	{
		if (scale < 0)
			scale = 0;
		String decimalPartStr = "";
		if (scale > 0)
		{
			decimalPartStr = decMust ? "0000000000" : "##########";
			if (scale > decimalPartStr.length())
				scale = decimalPartStr.length();
			decimalPartStr = (new StringBuilder(".")).append(decimalPartStr.substring(0, scale)).toString();
		}
		double d2 = round(d, scale, roundModle);
		String intPartStr = thousandSplit ? "###,###,###,###,###,###,###,###,###,##0" : "################################0";
		return formatDouble(d2, (new StringBuilder(String.valueOf(intPartStr))).append(decimalPartStr).toString());
	}

	public static double round_halfUp(double d, int scale)
	{
		return round(d, scale, 4);
	}

	public static String format(double d, int scale, boolean thousandSplit)
	{
		return formatDouble(d, scale, 4, thousandSplit, true);
	}

	public static double add(double v1, double v2)
	{
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.add(b2).doubleValue();
	}

	public static double subtract(double v1, double v2)
	{
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}

	public static double multiply(double v1, double v2)
	{
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.multiply(b2).doubleValue();
	}

	public static double multiply(double v1, double v2, int scale)
	{
		if (scale < 0)
		{
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		} else
		{
			BigDecimal b1 = new BigDecimal(v1);
			BigDecimal b2 = new BigDecimal(v2);
			return b1.multiply(b2).setScale(scale, 4).doubleValue();
		}
	}

	public static double divide(double v1, double v2)
	{
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.divide(b2).doubleValue();
	}

	public static double divide(double v1, double v2, int scale)
	{
		if (scale < 0)
		{
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		} else
		{
			BigDecimal b1 = new BigDecimal(v1);
			BigDecimal b2 = new BigDecimal(v2);
			return b1.divide(b2, scale, 4).doubleValue();
		}
	}

	public static double round(double v, int scale)
	{
		if (scale < 0)
		{
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		} else
		{
			BigDecimal b = new BigDecimal(v);
			return b.setScale(scale, 4).doubleValue();
		}
	}

	public static int getInt(String str, int defaultValue)
	{
		Integer num = null;
		if (RegexUtil.isInt(str, true))
			num = Integer.valueOf(str.trim());
		return num != null ? num.intValue() : defaultValue;
	}

	public static long getLong(String str, long defaultValue)
	{
		Long l = null;
		if (RegexUtil.isLong(str, true))
			l = new Long(str.trim());
		return l != null ? l.longValue() : defaultValue;
	}

	public static double getDouble(String str, double defaultValue, boolean acceptE)
	{
		Double d = null;
		if (RegexUtil.isDouble(str, true, acceptE))
			d = new Double(str.trim());
		return d != null ? d.doubleValue() : defaultValue;
	}
}
